﻿package code {
	// main class that runs the simulation
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
	
	// Hey Joe, how are you?  Mine kind of works, though I think I do something weird in spring.as.  Thanks,
	// Your favorite student, Blake (and Dustin)
	public class MainSim extends Sprite {
		private var ball:Ball;  // ball that drops
		private var bar:Bar;	// bar that rotates
		private var highWall:GameObject;	// higher wall 
		private var lowWall:GameObject;		// lower support wall for spring
		private var spring:Spring;			// spring that is attached to low wall and bar
		private var pin:Ball;		// pivot point
		private var collisionObjects:Array;  // an array of everything collidable
		private var previousTime:Number;	// variable that keeps track of the previous time
		private var attachedPoint:Vertex;	// the point the spring is attached to
		
		private var isPaused:Boolean;	//Is the game paused?		
		
		public function MainSim() {
			collisionObjects = new Array();
			previousTime = 0;
			
			//Set up buttons
			play_Btn.addEventListener(MouseEvent.CLICK, startSim);
			pause_Btn.addEventListener(MouseEvent.CLICK, pauseSim);
			reset_Btn.addEventListener(MouseEvent.CLICK, resetSim);
			
			isPaused = false; //Game begins un-paused
						
			init();
		}
		
		//Begin the Simulation once the "Start" Button is pressed
		public function startSim(e:Event):void
		{
			previousTime = getTimer();
			addEventListener(Event.ENTER_FRAME, update);
			isPaused = false;
		}
		
		//Pause the Sim
		public function pauseSim(e:Event):void
		{
			if(isPaused == false)
			{

				previousTime = getTimer(); // so that the getTimer stays in effect
				removeEventListener(Event.ENTER_FRAME, update);				
				isPaused = true;
			}
			
			else if(isPaused == true)
			{				
				
				addEventListener(Event.ENTER_FRAME, update);				
				isPaused = false;
			}
		}
		
		//Reset the Sim
		public function resetSim(e:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, update);
			previousTime = getTimer();
			//Clear the array, remove all objects in it from the screen
			for each(var g:GameObject in collisionObjects)
			{
				collisionObjects.splice(g);
				removeChild(g);
			}
			
			//Remove all other objects from the screen
			removeChild(ball);			
			removeChild(spring);
			removeChild(pin);
			
			//Initialize everything again
			init();
		}
		
		public function init(){
			makeBall();  // makes the initial ball
			makeBar();	 // makes the bar 
			makeWalls(); // makes the walls
			makeSpring(); // makes the spring
			makePin(); // makes the pin (is visual)
			
			springInit(); // initializes spring coordinates
		}
		
		// makes the ball.  
		public function makeBall(){
			ball = new Ball("Polygon", 10, 20, 0xFFFF00, 3, false);
			ball.x = 500;
			ball.y = 0;
			ball.createLinesArray();
			addChild(ball);
		}
		
		// makes the bar
		public function makeBar(){
			bar = new Bar("Rectangle", 460, 4, 0xFF00FF, 1, true, 15, 100, new Vertex(50, 200));
			bar.x = 50;
			bar.y = 200;
			bar.createLinesArray();
			bar.rotateBar();
			addChild(bar);
			collisionObjects.push(bar);
						
			bar.setUpVertices();
		}
		
		// makes the higher and lower walls
		public function makeWalls(){
			highWall = new GameObject("Rectangle", 100, 4, 0x0F0F0F, 1, false, 0, 10);
			highWall.x = 0;
			highWall.y = 300;
			highWall.createLinesArray();
			addChild(highWall);
			
			lowWall = new GameObject("Rectangle", 100, 4, 0x0F0F0F, 1, false, 0, 10);
			lowWall.x = 450;
			lowWall.y = 375;
			lowWall.createLinesArray();
			addChild(lowWall);
			
			collisionObjects.push(highWall, lowWall);
		}
		
		// makes the spring
		public function makeSpring(){
			spring = new Spring(bar.bottomRightVertex, new Vertex(lowWall.x + lowWall.shape.radius / 2 + 10, lowWall.y), 3, 0x123234, bar.bottomRightVertex, bar);
			addChild(spring);
		}
		
		public function makePin(){
			pin = new Ball("Polygon", 10, 20, 0xF23F00, 3, false);
			pin.x = bar.x - pin.shape.radius;
			pin.y = bar.y;
			addChild(pin);
		}
		
		// main update
		public function update(e:Event){
			var currentTime = getTimer();
			var timeDif = currentTime - previousTime; // calculate dt
			spring.springTo(bar);  // applies spring on bar
			
			ball.update(collisionObjects, timeDif);  // checks for collisions with ball
			bar.update(timeDif);
			
			adjustSprings();
			previousTime = currentTime;
		}
		
		
		// initalizes spring at certain position
		private function springInit():void{
			graphics.clear();
			graphics.lineStyle(spring.thickness, spring.color);
			graphics.moveTo(spring.a.x, spring.a.y);
			graphics.lineTo(spring.b.x, spring.b.y);
		}
		
		//------------------------------------------------------------------------
		// Adjust springs:
		//------------------------------------------------------------------------
		private function adjustSprings():void {
			spring.update(bar.bottomRightVertex);
			springInit();
		}
		


	}
	
}
